package net.qhzw.vip.qiyu.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import net.qhzw.vip.qiyu.entity.*;
import net.qhzw.vip.qiyu.handler.ApiException;
import net.qhzw.vip.qiyu.mapper.SysRoleMapper;
import net.qhzw.vip.qiyu.model.AddRoleForm;
import net.qhzw.vip.qiyu.model.RoleMenuVo;
import net.qhzw.vip.qiyu.service.*;
import net.qhzw.vip.qiyu.util.PinyinUtils;
import net.qhzw.vip.qiyu.util.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;

@Service
@Slf4j
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {

    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private SysRoleMenuService sysRoleMenuService;

    @Autowired
    private SysMenuService sysMenuService;

    @Autowired
    private ShopService shopService;

    @Override
    public boolean isSuperAdmin(Long userId) {
        // 当用户的角色code 为：ROLE_ADMIN 时，该用户为超级的管理员
        // 用户的id->用户的角色->该角色的Code是否为ROLE_ADMIN
        String roleCode = sysRoleMapper.getUserRoleCode(userId);
        if (!StringUtils.isEmpty(roleCode) && "ROLE_ADMIN".equals(roleCode)) {
            return true;
        }
        return false;
    }

    @Override
    public Map<String, Object> findByPage(Page<SysRole> page, Long shopId, String name) {
        Map<String, Object> result = new HashMap<>();
        List<RoleMenuVo> roleMenuVos = sysRoleMenuService.findByPage(page, shopId, name);
        //PageInfo<RoleMenuVo> pageInfo = new PageInfo<>(roleMenuVos);
        int count = count(new LambdaQueryWrapper<SysRole>()
                .like(!StringUtils.isEmpty(name), SysRole::getName, name));
        result.put("count", count);
        result.put("records", roleMenuVos);
        return result;
    }

    /***
     * 新增角色
     * @param roleForm
     * @return
     */
    @Override
    public boolean addSysRole(Long shopId, AddRoleForm roleForm) {
        log.info("新增角色,{}", JSON.toJSONString(roleForm, true));
        SysRole role = addRoleInfo(shopId, roleForm);
        if (save(role)) {
            //新增中间表
            return saveRoleMenu(roleForm.getMenus(), role.getId());
        }
        return false;
    }

    /***
     * 修改角色
     * @param roleForm
     * @return
     */
    @Override
    public boolean updateRoleById(AddRoleForm roleForm) {
        log.info("修改角色, {}", JSON.toJSONString(roleForm, true));
        SysRole role = new SysRole();
        Long roleId = roleForm.getId();
        role.setId(roleId);
        role.setName(roleForm.getName());
        role.setCode(roleForm.getCode());
        role.setDescription(roleForm.getDescription());
        role.setLastUpdateTime(new Date());
        role.setModifyBy(SecurityUtils.getUserId());
        boolean update = updateById(role);
        if (update) {
            if (!CollectionUtils.isEmpty(roleForm.getMenus())) {
                //int remove =  sysRoleMenuService.deleteByRoleIdAndMenuId(roleForm.getId(), roleForm.getMenus());
                sysRoleMenuService.remove(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getRoleId, roleForm.getId()));
                return saveRoleMenu(roleForm.getMenus(), roleId);
            }
        }
        return false;
    }

    /***
     * 查询角色下的菜单
     * @param id
     * @return
     */
    @Override
    public RoleMenuVo getSysRole(Long id) {
        SysRole sysRole = getById(id);
        List<SysRoleMenu> sysRoleMenus = sysRoleMenuService.list(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getRoleId, id));
        List<SysMenu> sysMenus = new ArrayList<>();
        for (SysRoleMenu sysRoleMenu : sysRoleMenus) {
            SysMenu sysMenu = sysMenuService.getById(sysRoleMenu.getMenuId());
            sysMenus.add(sysMenu);
        }
        RoleMenuVo roleMenuVo = new RoleMenuVo();
        BeanUtils.copyProperties(sysRole, roleMenuVo);
        roleMenuVo.setPermissions(sysMenus);
        return roleMenuVo;
    }

    /***
     * 根据角色id查询角色名称
     * @param roleId
     * @return
     */
    @Override
    public String getRoleNameById(Long roleId) {
        SysRole sysRole = getById(roleId);
        if (sysRole != null) {
            return sysRole.getName();
        }
        return null;
    }


    /***
     * 根据userId查询角色code
     * @param userId
     * @return
     */
    @Override
    public String getRoleCodeByUserId(Long userId) {
        return sysRoleMapper.getRoleCodeByUserId(userId);
    }

    @Autowired
    private SysUserService sysUserService;

    /**
     * 根据userId查询角色信息
     *
     * @param userId
     * @return
     */
    @Override
    public SysRole getRoleByUserId(Long userId) {
        SysUser sysUser = sysUserService.getById(userId);
        if (sysUser != null && sysUser.getParentId() != 0) {
            userId = sysUser.getParentId();
        }
        return sysRoleMapper.getRoleByUserId(userId);
    }

    /***
     * 添加角色菜单中间表
     * @param menuIds
     * @param roleId
     * @return
     */
    private boolean saveRoleMenu(List<Long> menuIds, Long roleId) {
        if (!CollectionUtils.isEmpty(menuIds)) {
            List<SysRoleMenu> sysRoleMenus = new ArrayList<>();
            for (Long menu : menuIds) {
                SysRoleMenu roleMenu = new SysRoleMenu();
                roleMenu.setId(IdWorker.getId());
                roleMenu.setMenuId(menu);
                roleMenu.setRoleId(roleId);
                sysRoleMenus.add(roleMenu);
            }
            return sysRoleMenuService.saveBatch(sysRoleMenus);
        }
        return false;
    }

    /***
     * 角色数据初始化
     * @param roleForm
     * @return
     */
    private SysRole addRoleInfo(Long shopId, AddRoleForm roleForm) {
        Long userId = SecurityUtils.getUserId();
        String roleCode = "";
        if (shopId != 1) {
            Shop shop = shopService.getById(shopId);
            if (shop == null) {
                throw new ApiException("获取不到当前租户信息, 请联系管理员!");
            }
            String shopName = shop.getShortName();
            roleCode = PinyinUtils.toPinyin(shopName);
        }

        SysRole role = new SysRole();
        role.setName(roleForm.getName());
        role.setCode(roleCode + "_" + roleForm.getCode());
        role.setDescription(roleForm.getDescription());
        role.setShopId(shopId);
        role.setId(IdWorker.getId());
        role.setCreateBy(Long.valueOf(userId));
        role.setModifyBy(Long.valueOf(userId));
        role.setStatus((byte) 1);
        role.setCreated(new Date());
        role.setLastUpdateTime(new Date());
        return role;
    }
}
